#include "cpu_card.h"
#include "mifare_card.h"
#include "ic_des.h"

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

inline  s32 mifare_card_check_key(reader_op *reader, u8 block, u8 key_type)
{
	s32 ret;
	reader_data send, recv;

	if (!reader) {
		printf("mifare_check_key pare error!!!\n");
		return RET_ERR;
	}

	send.data = reader->send_data;
	recv.data = reader->recv_data;

	memset(send.data, 0, READER_BUF_SIZ);
	memcpy(send.data, reader->deal_in_data.m1.key_data, 6);

	/* 验证密钥 */
	send.type    = READER_CONTACTLESS_M1;
	send.cla	 = 0x00;
	send.cmd.ins = RC500_AUTHENTICATION;
	send.pa1.p1  = key_type; 
	send.pa2.p2  = block;  
	send.len.lc  = 0x06; 
	send.le      = 0x00; 
	
	ret = reader_communication(reader->fd, &send, &recv);
	return ret;
}


inline s32 mifare_card_read_block(reader_op *reader, u8 block)
{
	s32 ret;
	reader_data send, recv;

	send.data 			= reader->send_data; 
	recv.data           = reader->recv_data;
	
	/* 读取块数据 */
	memset(send.data, 0, READER_BUF_SIZ);
	send.type    		= READER_CONTACTLESS_M1;
	send.cla	 		= 0x00;
	send.cmd.mf_comm	= RC500_READ_CARD;
	send.pa1.mf_flag	= 0x00; 
	send.pa2.mf_sector	= block;
	send.len.mf_len		= 0x00; 

	ret = reader_communication(reader->fd, &send, &recv);
	if (ret) {
		printf("mifare_card_read_block failed!!! errno: [%02x%02x]\n", \
			recv.sw1, recv.sw2);
		return RET_ERR;
	}
	else {
		return recv.len.mf_len;
	}
}


static inline int mifare_card_get_tac(reader_op *reader)
{
	s32 ret = 0;
	reader_data send, recv;

	send.data = reader->send_data;
	recv.data = reader->recv_data;

	memcpy(send.data, reader->deal_in_data.card_num, 8); // 分散因子 由4字节卡片CSN + 4字节物理CSN 寻卡时得出
	/* PSAM通用DES初始化-获得子密钥 */
	send.type    = READER_CONTACT_SAM1;
	send.cla	 = 0x80;
	send.cmd.ins = APDU_INIT_FOR_DESCRYPT;
	send.pa1.p1  = CTCC_YJD_KEY_FLAG_TAC; 
	send.pa2.p2  = CTCC_YJD_KEY_ID;  
	send.len.lc  = 0x08; 
	send.le      = 0x00; 

	ret = reader_communication(reader->fd, &send, &recv);
	if (((recv.sw1 << 8) | recv.sw2) != 0x9000) {
		printf("mifare_card_get_tac no.1 failed!!! errno: [%02x%02x]\n", \
			recv.sw1, recv.sw2);

		return ((recv.sw1 << 8) | recv.sw2);
	}

	memset(send.data, 0, READER_BUF_SIZ);
	send.data[0] = 0x01;
	send.data[1] = 0x08;
	send.data[2] = reader->psam_out_data.terminal[0];
	send.data[3] = reader->psam_out_data.terminal[1];
	send.data[4] = reader->psam_out_data.terminal[2];
	send.data[5] = reader->psam_out_data.terminal[3];
	send.data[6] = reader->psam_out_data.terminal[4];
	send.data[7] = reader->psam_out_data.terminal[5];
	send.data[8] = reader->psam_out_data.deal_index[0];
	send.data[9] = reader->psam_out_data.deal_index[1];
	send.data[10] = reader->psam_out_data.deal_index[2];
	send.data[11] = reader->psam_out_data.deal_index[3];
	send.data[12] = 0x00;
	send.data[13] = 0x01;
	send.data[14] = 0x00;
	send.data[15] = 0x00;
	send.data[16] = 0x00;
	send.data[17] = 0x00;
	send.data[18] = 0x00;
	send.data[19] = 0x00;
	send.data[20] = reader->deal_in_data.money_val[0];
	send.data[21] = reader->deal_in_data.money_val[1];
	send.data[22] = reader->deal_in_data.money_val[2];
	send.data[23] = reader->deal_in_data.money_val[3];
	send.data[24] = reader->deal_in_data.deal_val[0];
	send.data[25] = reader->deal_in_data.deal_val[1];
	send.data[26] = reader->deal_in_data.deal_val[2];
	send.data[27] = reader->deal_in_data.deal_val[3];
	send.data[28]  = reader->deal_in_data.deal_time[0];
	send.data[29]  = reader->deal_in_data.deal_time[1];
	send.data[30]  = reader->deal_in_data.deal_time[2];
	send.data[31]  = reader->deal_in_data.deal_time[3];
	send.data[32]  = reader->deal_in_data.deal_time[4]; 
	send.data[33]  = reader->deal_in_data.deal_time[5]; 
	send.data[34]  = reader->deal_in_data.deal_time[6];
	send.data[35] = 0x00;
	send.data[36] = 0x00;
	send.data[37] = reader->deal_out_data.deal_cnt[0];
	send.data[38] = reader->deal_out_data.deal_cnt[1];
	send.data[39] = 0x80;

	
	/* PSAM DES计算-获得过程密钥 */
	send.type    = READER_CONTACT_SAM1;
	send.cla	 = 0x80;
	send.cmd.ins = APDU_DES_CRYPT;
	send.pa1.p1  = 0x05; 
	send.pa2.p2  = 0x00; 
	send.len.lc  = 40; 
	send.le      = 0x00; 

	ret = reader_communication(reader->fd, &send, &recv);
	if (recv.sw1 == 0x61) {
		psam_apdu_get_response(&send, &recv);
		ret = reader_communication(reader->fd, &send, &recv);
	}
	
	if (((recv.sw1 << 8) | recv.sw2) != 0x9000) {
		printf("mifare_card_get_tac no.2 failed!!! errno: [%02x%02x]\n", \
			recv.sw1, recv.sw2);
		return ((recv.sw1 << 8) | recv.sw2);
	}

	// 获得TAC值
	reader->deal_out_data.deal_tac[0] = recv.data[0];
	reader->deal_out_data.deal_tac[1] = recv.data[1];
	reader->deal_out_data.deal_tac[2] = recv.data[2];
	reader->deal_out_data.deal_tac[3] = recv.data[3];

	if (DEBUG_APP_WALL > __DEBUG_APP_O1__) {
		printf("mifare_card_deal: get tac success: tac_val[%02x-%02x-%02x-%02x]\n", \
			reader->deal_out_data.deal_tac[0], reader->deal_out_data.deal_tac[1], \
			reader->deal_out_data.deal_tac[2], reader->deal_out_data.deal_tac[3]);
	}
	
	return RET_OK;
}


inline static s32 mifare_card_write(reader_op *reader, u8 block, s8 *block_data, u8 len)
{
	s32 ret = 0;
	reader_data send, recv;

	send.data 			= block_data; 
	recv.data           = reader->recv_data;

	send.type    		= READER_CONTACTLESS_M1;
	send.cla	 		= 0x00;
	send.cmd.mf_comm	= RC500_WRITE_CARD;
	send.pa1.mf_flag	= 0x00; 
	send.pa2.mf_sector	= block;
	send.len.mf_len		= len; 

	ret = reader_communication(reader->fd, &send, &recv);
	if (ret) {
		printf("mifare card read block failed!!! errno: [%02x%02x]\n", \
			recv.sw1, recv.sw2);
		return RET_ERR;
	}

	return RET_OK;
}


s32 mifare_card_deal(void *op)
{
	reader_data send, recv;
	s8 block_data[16] = {0, 0, 0};
	u8 i = 0;
	u8 idx = 0;
	u16 deal_cnt = 0; // 交易次数
	reader_op *reader = (reader_op *)op;
	s32 ret = 0;
	u32 deal_val = 0;
	u32 discount_val = 0; 
	u32 money_val = 0;
	u32 money_val_data[4] = {0, 0, 0};


	if (!op) {
		printf("mifare_card_deal pare error!!!\n");
		return RET_ERR;
	}


	send.data = reader->send_data;
	recv.data = reader->recv_data;
	ret = reader_get_factor(reader);
	if (ret) {
		return RET_ERR;
	}


	send.data = reader->send_data;
	recv.data = reader->recv_data;
	reader->op_type = READER_DEAL_OP_FLAG;
	ret = psam_card_get_key(reader, CTCC_YJD_KEY_FLAG, \
		CTCC_YJD_KEY_ID); // 获取key密钥
	if (ret) {
		return RET_ERR;
	}



	/* 终端交易序号-取记录的数据库序号 */
	reader->psam_out_data.deal_index[0]	 = reader->deal_in_data.index[0];
	reader->psam_out_data.deal_index[1]  = reader->deal_in_data.index[1];
	reader->psam_out_data.deal_index[2]  = reader->deal_in_data.index[2];
	reader->psam_out_data.deal_index[3]  = reader->deal_in_data.index[3];

	ret = mifare_card_check_key(reader, S8B3, MIFARE_KB);
	if (ret) {
		return RET_ERR;
	}

	ret = mifare_card_read_block(reader, S8B0);
	if (ret <= 0) {
		return RET_ERR;
	}
	else {
		if (ret > sizeof(block_data)) {
			memcpy(block_data, reader->recv_data, 16);
		}
		else {
			memcpy(block_data, reader->recv_data, ret);
		}
	}


	if (DEBUG_APP_WALL > __DEBUG_APP_O1__) {
		printf("mifare_card_deal: read [S8B0] block data success\n");
	}

	if (reader->deal_in_data.deal_type == 0x01) {
		deal_cnt = (block_data[1] << 8) | block_data[2];
		deal_cnt++;
		block_data[1] = deal_cnt >> 8; // 高8位
		block_data[2] = deal_cnt & 0xFF;
	}
	else {
		deal_cnt = (block_data[7] << 8) | block_data[8];
		deal_cnt++;
		block_data[7] = deal_cnt >> 8; // 高8位
		block_data[8] = deal_cnt & 0xFF;
	}

	reader->deal_out_data.deal_cnt[0] = deal_cnt >> 8;
	reader->deal_out_data.deal_cnt[1] = deal_cnt & 0xFF;
	ret = mifare_card_get_tac(reader);
	if (ret) {
		return RET_ERR;
	}

	memset(send.data, 0, READER_BUF_SIZ);
	send.data[0] = reader->deal_out_data.deal_cnt[0];
	send.data[1] = reader->deal_out_data.deal_cnt[1];
	send.data[2] = reader->deal_in_data.deal_val[0];
	send.data[3] = reader->deal_in_data.deal_val[1];
	send.data[4] = reader->deal_in_data.deal_val[2];
	send.data[5] = reader->deal_in_data.deal_val[3];
	send.data[6] = reader->deal_in_data.deal_type;	
	send.data[7] = reader->psam_out_data.terminal[0];
	send.data[8] = reader->psam_out_data.terminal[1];
	send.data[9] = reader->psam_out_data.terminal[2];
	send.data[10] = reader->psam_out_data.terminal[3];
	send.data[11]  = reader->deal_in_data.deal_time[0];
	send.data[12]  = reader->deal_in_data.deal_time[1];
	send.data[13]  = reader->deal_in_data.deal_time[2];
	send.data[14]  = reader->deal_in_data.deal_time[3];
	send.data[15] = cel_crc(send.data, 15);

	switch (block_data[0]) { // 确定扇区首块地址(环形记录块 共9条记录)
		case 1:
		case 2:
		case 3:
			idx = S2B0;
			break;
			
		case 4:
		case 5:
		case 6:
			idx = S3B0;
			break;
			
		case 7:
		case 8:
		case 9:
			idx = S4B0;
			break;
			
		default:
			block_data[0] = 1;
			idx = S2B0;
			break;
	}

	ret = mifare_card_check_key(reader, idx+3, MIFARE_KB);
	if (ret) {
		return RET_ERR;
	}

	idx +=  (block_data[0]-1)%3; // 确定块
	ret = mifare_card_write(reader, idx, send.data, 16);
	if (ret) {
		return RET_ERR;
	}
	
	if (DEBUG_APP_WALL > __DEBUG_APP_O1__) {
		printf("mifare_card_deal: write [%02d] block success\n", idx);
	}

	block_data[0] = idx + 1;
	if (reader->deal_in_data.deal_type == 0x01) {
		block_data[5] = 0x01; // 钱包开始
	}
	else {
		block_data[5] = 0x03; // 补贴钱包开始
	}

	block_data[15] = cel_crc(block_data, 15);

	// 写交易配置与控制信息
	ret = mifare_card_check_key(reader, S8B3, MIFARE_KB);
	if (ret) {
		return RET_ERR;
	}

	ret = mifare_card_write(reader, S8B0, block_data, 16);
	if (ret) {
		return RET_ERR;
	}

	ret = mifare_card_write(reader, S8B1, block_data, 16);
	if (ret) {
		return RET_ERR;
	}

	if (DEBUG_APP_WALL > __DEBUG_APP_O1__) {
		printf("mifare_card_deal: write [S8B0 S8B1] block success\n");
	}



	// 写入钱包数据
	deal_val = ((reader->deal_in_data.deal_val[3] << 24) | \
		(reader->deal_in_data.deal_val[2] << 16) | \
		(reader->deal_in_data.deal_val[1] << 8) | \
		(reader->deal_in_data.deal_val[0]));
	discount_val = ((reader->deal_in_data.deal_rebate[3] << 24) | \
		(reader->deal_in_data.deal_rebate[2] << 16) | \
		(reader->deal_in_data.deal_rebate[1] << 8) | \
		(reader->deal_in_data.deal_rebate[0]));

	money_val = ((reader->deal_in_data.money_val[3] << 24) | \
		(reader->deal_in_data.money_val[2] << 16) | \
		(reader->deal_in_data.money_val[1] << 8) | \
		(reader->deal_in_data.money_val[0]));


	if (DEBUG_APP_WALL > __DEBUG_APP_O1__) {
		printf("mifare_card_deal: no.1 money_val [%x]\n", money_val);
	}

	if (money_val < deal_val) {
		printf("mifare_card_deal: money less\n");
		reader->deal_in_data.deal_ret = DEAL_RESULT_MONEY_LESS;
		return RET_ERR;
	}
	else {
		money_val -= deal_val;
	}

	
	if (reader->deal_in_data.m1.endian == APP_BIG_ENDIAN) {
		money_val_data[0] = (((money_val >> 24) & 0xFF) | \
			(((money_val >> 8)  & 0xFF00) | \
			((money_val << 8)  & 0xFF0000) | \
			((money_val << 24) & 0xFF000000)));

	}
	else {
		money_val_data[0] = money_val;
	}

	if (DEBUG_APP_WALL > __DEBUG_APP_O1__) {
		printf("mifare_card_deal: no.2 money_val [%x]\n", money_val_data[0]);
	}


	money_val_data[1] = ~money_val_data[0];
	money_val_data[2] = money_val_data[0];
	money_val_data[3] = 0xFF00FF00;

	if (reader->deal_in_data.deal_type == 0x01) {
		idx = S1B0;
	}
	else {
		idx = S5B0;
	}

	ret = mifare_card_check_key(reader, idx+3, MIFARE_KB);
	if (ret) {
		return RET_ERR;
	}

	ret = mifare_card_write(reader, idx, (s8 *)money_val_data, 16);
	if (ret) {
		return RET_ERR;
	}

	ret = mifare_card_write(reader, idx+1, (s8 *)money_val_data, 16);
	if (ret) {
		return RET_ERR;
	}

	if (DEBUG_APP_WALL > __DEBUG_APP_O1__) {
		printf("mifare_card_deal: write [%02d %02d] block success\n", idx, idx+1);
	}



	// 写入配置信息
	if (reader->deal_in_data.deal_type == 0x01) {
		block_data[5] = 0x02;
	}
	else {
		block_data[5] = 0x04;
	}
	
	block_data[15] = cel_crc(block_data, 15);

	ret = mifare_card_check_key(reader, S8B3, MIFARE_KB);
	if (ret) {
		return RET_ERR;
	}

	ret = mifare_card_write(reader, S8B0, block_data, 16);
	if (ret) {
		return RET_ERR;
	}

	ret = mifare_card_write(reader, S8B1, block_data, 16);
	if (ret) {
		return RET_ERR;
	}
	
	if (DEBUG_APP_WALL > __DEBUG_APP_O1__) {
		printf("mifare_card_deal: write [S8B0 S8B1] block success\n");
	}
	reader->deal_in_data.deal_ret = DEAL_RESULT_NORMAL;

	if (DEBUG_APP_WALL > __DEBUG_APP_O0__) {
		printf("mifare_card_deal done\n");
	}

	return RET_OK;
}

 

